
/**
** \file       option_parser.c
**
** \brief      This file contains the functions who handle the parser option
**
** \authors    Ben M'rad Hanna, Boillot Ulysse, De Oliveira Guillaume,
**             Laterem Hamza et Nguyen Viet Dung coded this file as a part
**             of the 42sh project.
**
** \version    0.8
**
** \data       26 November 2010
**
*/

#include "options_parser.h"

static int              ret2(int                        i,
                             char                       *tmp)
{
  free(tmp);

  return (i);
}

static int              arg_missing(char                *opt)
{
  write(STDERR_FILENO, "Error: option", 13);
  write(STDERR_FILENO, opt, strlen(opt));
  write(STDERR_FILENO, " needs an argument\n", 19);

  return (1);
}

static int              version(int                     fd)
{
  write(fd, "Version 0.8\n", 13);
  write(fd, "42sh\n", 6);

  return (0);
}

static s_cmd            *add_file(char                  *file,
                                  s_cmd                 *cmd_res)
{
  s_file                *tmp = NULL;
  s_file                *new = NULL;

  tmp = cmd_res->file;
  new = malloc(sizeof (s_file));
  new->name = malloc(sizeof (char) * strlen(file));
  new->name = strcpy(new->name, file);

  if (tmp == NULL)
    cmd_res->file = new;
  else
  {
    while (tmp->next != NULL)
      tmp = tmp->next;

    tmp->next = new;
  }

  return (cmd_res);
}

static s_cmd            *add_cmd_opt(char               *tm,
                                     char               *str,
                                     s_cmd              *cmd_res)
{
  s_opt                 *tmp = NULL;
  s_opt                 *new = NULL;

  tmp = cmd_res->opt;
  new = malloc(sizeof (s_opt));
  new->name = malloc(sizeof (char) * strlen(tm) + 1);
  new->name = strcpy(new->name, tm);

  if (str != NULL)
  {
    new->aux = malloc(sizeof (char) * strlen(str) + 1);
    new->aux = strcpy(new->aux, str);
  }
  else
    new->aux = NULL;

  new->next = NULL;

  if (tmp == NULL)
    cmd_res->opt = new;
  else
  {
    while (tmp->next != NULL)
      tmp = tmp->next;

    tmp->next = new;
  }

  return (cmd_res);
}

static int              test_opt(int                    argc,
                                 char                   **argv,
                                 int                    *i,
                                 char                   *tmp,
                                 s_cmd                  *cmd_res)
{
  if (argc <= ((*i) + 1))
    return (arg_missing(tmp));

  *i = (*i) + 1;

  cmd_res = add_cmd_opt(tmp, argv[*i], cmd_res);
  return (0);
}

static int              my_free(char                    *tmp)
{
  free(tmp);
  return (0);
}

static int              commande_line(int               argc,
                                      char              **argv,
                                      s_cmd             *cmd_res)
{
  char                  *tmp = NULL;
  char                  *tmp2 = NULL;
  int                   i = 1;

  tmp = malloc(sizeof (char) * 2);

  for (i = 1; i < argc; ++i)
  {
    if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "-o")
        || (!strcmp(argv[i], "+o")))
    {
      tmp = strcpy(tmp, argv[i]);

      if ((test_opt(argc, argv, &i, tmp, cmd_res)) != 0)
        return (ret2(1, tmp));
    }
    else
    {
      if (!strcmp(argv[i], "--version"))
        return (version(STDOUT_FILENO));

      if (!strcmp(argv[i], (tmp2 = "--ast-print")) ||
	  !strcmp(argv[i], (tmp2 = "--norc")))
        add_cmd_opt(tmp2, NULL, cmd_res);
      else
        cmd_res = add_file(argv[i], cmd_res);
    }
  }

  return (my_free(tmp));
}

s_cmd                   *option_parser(int              argc,
                                       char             **argv,
                                       int              *ret)
{
  s_cmd                 *cmd_res = NULL;
  int                   retr;

  cmd_res = malloc(sizeof (s_cmd));
  cmd_res->opt = NULL;
  cmd_res->file = NULL;

  if ((retr = commande_line(argc, argv, cmd_res)) != 0)
  {
    *ret = 1;
    return (NULL);
  }
  *ret = 0;
  return (cmd_res);
}
